using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using EPiAbstractions;
using EPiServer.Community.Blog;
using EPiServer.Core;
using JoelAbrahamsson.BlogExtensions;
using JoelAbrahamsson.PageTypes;
using JoelAbrahamsson.XmlSitemap;

namespace JoelAbrahamsson.Web.Controllers
{
    public class SitemapController : Controller
    {
        ExtendedBlogHandlerFacade _blogHandlerFacade;
        IDataFactoryFacade _dataFactoryFacade;
        Blog _blog;
        List<ISitemapItem> _items;

        public SitemapController(ExtendedBlogHandlerFacade blogHandlerFacade, IDataFactoryFacade dataFactoryFacade)
        {
            _blogHandlerFacade = blogHandlerFacade;
            _dataFactoryFacade = dataFactoryFacade;
        }

        public XmlSitemapResult Xml(Blog blog)
        {
            _blog = blog;

            _items = new List<ISitemapItem>();

            AddEntries();

            AddPages();

            return new XmlSitemapResult(_items);
        }

        private void AddEntries()
        {
            int totalItems;
            EntryCollection entries = _blogHandlerFacade.GetLatestEntries(_blog, 1, int.MaxValue - 1, out totalItems);

            
            foreach (Entry entry in entries)
            {
                _items.Add(
                    new SitemapItem(entry.GetUrl(ControllerContext.RequestContext))
                        {
                            LastModified = GetEntryLastModified(entry),
                            Priority = 1
                        }
                    );
            }
        }

        private DateTime GetEntryLastModified(Entry entry)
        {
            if (entry.Updated > entry.PublicationStart)
                return entry.Updated;

            return entry.PublicationStart;
        }

        private void AddPages()
        {
            IEnumerable<BasePageData> pagesToShowInMenu = _dataFactoryFacade.GetChildren(PageReference.StartPage)
                .Where(page => page.CheckPublishedStatus(PagePublishedStatus.Published) && page.VisibleInMenu && page is BasePageData)
                .Cast<BasePageData>();

            foreach (BasePageData page in pagesToShowInMenu)
            {
                AddPage(page);
            }
        }

        private void AddPage(BasePageData page)
        {
            string url = "http://" + System.Configuration.ConfigurationManager.AppSettings["defaultDomain"];

            url += Url.RouteUrl(new RouteValueDictionary(new
               {
                   controller = page.ControllerName,
                   action = "Index",
                   slug = page.Slug
               }));

            SitemapItem item = new SitemapItem(url)
               {
                   LastModified = page.Saved,
                   ChangeFrequency = ChangeFrequency.Weekly,
                   Priority = 1
               };

            _items.Add(item);
        }
    }
}
